{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# A Uniform interface to call different LLMs\n",
    "\n",
    "Autogen provides a uniform interface for API calls to different LLMs, and creating LLM agents from them.\n",
    "Through setting up a configuration file, you can easily switch between different LLMs by just changing the model name, while enjoying all the enhanced features such as caching and cost calculation!\n",
    "\n",
    "In this notebook, we will show you how to use AG2 to call different LLMs and create LLM agents from them.\n",
    "\n",
    "Currently, we support the following model families:\n",
    "- [OpenAI](https://platform.openai.com/docs/overview)\n",
    "- [Azure OpenAI](https://azure.microsoft.com/en-us/products/ai-services/openai-service)\n",
    "- [Anthropic Claude](https://docs.anthropic.com/en/docs/welcome)\n",
    "- [Google Gemini](https://ai.google.dev/gemini-api/docs)\n",
    "- [Mistral](https://docs.mistral.ai/) (API to open and closed-source models)\n",
    "- [DeepInfra](https://deepinfra.com/) (API to open-source models)\n",
    "- [TogetherAI](https://www.together.ai/) (API to open-source models)\n",
    "\n",
    "... and more to come!\n",
    "\n",
    "You can also [plug in your local deployed LLM](https://docs.ag2.ai/latest/docs/blog/2024/01/26/Custom-Models) into AG2 if needed."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Install required packages\n",
    "\n",
    "You may want to install AG2 with options to different LLMs. Here we install AG2 with all the supported LLMs.\n",
    "By default, AG2 is installed with OpenAI support.\n",
    "    \n",
    "```bash\n",
    "pip install autogen[openai,gemini,anthropic,mistral,together]\n",
    "```\n",
    "\n",
    "\n",
    "## Config list setup\n",
    "\n",
    "\n",
    "First, create a `OAI_CONFIG_LIST` file to specify the api keys for the LLMs you want to use.\n",
    "Generally, you just need to specify the `model`, `api_key` and `api_type` from the provider.\n",
    "\n",
    "```python\n",
    "[\n",
    "    {   \n",
    "        # using OpenAI\n",
    "        \"model\": \"gpt-35-turbo-1106\", \n",
    "        \"api_key\": \"YOUR_API_KEY\"\n",
    "        # default api_type is openai\n",
    "    },\n",
    "    {\n",
    "        # using Azure OpenAI\n",
    "        \"model\": \"gpt-4-turbo-1106\",\n",
    "        \"api_key\": \"YOUR_API_KEY\",\n",
    "        \"api_type\": \"azure\",\n",
    "        \"base_url\": \"YOUR_BASE_URL\",\n",
    "        \"api_version\": \"YOUR_API_VERSION\"\n",
    "    },\n",
    "    {   \n",
    "        # using Google gemini\n",
    "        \"model\": \"gemini-1.5-pro-latest\",\n",
    "        \"api_key\": \"YOUR_API_KEY\",\n",
    "        \"api_type\": \"google\"\n",
    "    },\n",
    "    {\n",
    "        # using DeepInfra\n",
    "        \"model\": \"meta-llama/Meta-Llama-3-70B-Instruct\",\n",
    "        \"api_key\": \"YOUR_API_KEY\",\n",
    "        \"base_url\": \"https://api.deepinfra.com/v1/openai\" # need to specify the base_url\n",
    "    },\n",
    "    {\n",
    "        # using Anthropic Claude\n",
    "        \"model\": \"claude-1.0\",\n",
    "        \"api_type\": \"anthropic\",\n",
    "        \"api_key\": \"YOUR_API_KEY\"\n",
    "    },\n",
    "    {\n",
    "        # using Mistral\n",
    "        \"model\": \"mistral-large-latest\",\n",
    "        \"api_type\": \"mistral\",\n",
    "        \"api_key\": \"YOUR_API_KEY\"\n",
    "    },\n",
    "    {\n",
    "        # using TogetherAI\n",
    "        \"model\": \"google/gemma-7b-it\",\n",
    "        \"api_key\": \"YOUR_API_KEY\",\n",
    "        \"api_type\": \"together\"\n",
    "    }\n",
    "    ...\n",
    "]\n",
    "```\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Uniform Interface to call different LLMs\n",
    "We first demonstrate how to use AG2 to call different LLMs with the same wrapper class.\n",
    "\n",
    "After you install relevant packages and setup your config list, you only need three steps to call different LLMs:\n",
    "1. Extract the config with the model name you want to use.\n",
    "2. create a client with the model name.\n",
    "3. call the client `create` to get the response.\n",
    "\n",
    "Below, we define a helper function `model_call_example_function` to implement the above steps."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import autogen\n",
    "from autogen import OpenAIWrapper\n",
    "\n",
    "\n",
    "def model_call_example_function(model: str, message: str, cache_seed: int = 41, print_cost: bool = False):\n",
    "    \"\"\"A helper function that demonstrates how to call different models using the OpenAIWrapper class.\n",
    "    Note the name `OpenAIWrapper` is not accurate, as now it is a wrapper for multiple models, not just OpenAI.\n",
    "    This might be changed in the future.\n",
    "    \"\"\"\n",
    "    config_list = autogen.config_list_from_json(\n",
    "        \"OAI_CONFIG_LIST\",\n",
    "        filter_dict={\n",
    "            \"model\": [model],\n",
    "        },\n",
    "    )\n",
    "    client = OpenAIWrapper(config_list=config_list)\n",
    "    response = client.create(messages=[{\"role\": \"user\", \"content\": message}], cache_seed=cache_seed)\n",
    "\n",
    "    print(f\"Response from model {model}: {response.choices[0].message.content}\")\n",
    "\n",
    "    # Print the cost of the API call\n",
    "    if print_cost:\n",
    "        client.print_usage_summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "model_call_example_function(model=\"gpt-35-turbo-1106\", message=\"Tell me a joke.\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "model_call_example_function(model=\"gemini-1.5-pro-latest\", message=\"Tell me a joke.\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "model_call_example_function(model=\"meta-llama/Meta-Llama-3-70B-Instruct\", message=\"Tell me a joke. \")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "model_call_example_function(model=\"mistral-large-latest\", message=\"Tell me a joke. \", print_cost=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Using different LLMs in agents\n",
    "Below we give a quick demo of using different LLMs agents in a groupchat. \n",
    "\n",
    "We mock a debate scenario where each LLM agent is a debater, either in affirmative or negative side. We use a round-robin strategy to let each debater from different teams to speak in turn."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_llm_config(model_name):\n",
    "    return {\n",
    "        \"config_list\": autogen.config_list_from_json(\"OAI_CONFIG_LIST\", filter_dict={\"model\": [model_name]}),\n",
    "        \"cache_seed\": 41,\n",
    "    }\n",
    "\n",
    "\n",
    "affirmative_system_message = \"You are in the Affirmative team of a debate. When it is your turn, please give at least one reason why you are for the topic. Keep it short.\"\n",
    "negative_system_message = \"You are in the Negative team of a debate. The affirmative team has given their reason, please counter their argument. Keep it short.\"\n",
    "\n",
    "gpt35_agent = autogen.AssistantAgent(\n",
    "    name=\"GPT35\", system_message=affirmative_system_message, llm_config=get_llm_config(\"gpt-35-turbo-1106\")\n",
    ")\n",
    "\n",
    "llama_agent = autogen.AssistantAgent(\n",
    "    name=\"Llama3\",\n",
    "    system_message=negative_system_message,\n",
    "    llm_config=get_llm_config(\"meta-llama/Meta-Llama-3-70B-Instruct\"),\n",
    ")\n",
    "\n",
    "mistral_agent = autogen.AssistantAgent(\n",
    "    name=\"Mistral\", system_message=affirmative_system_message, llm_config=get_llm_config(\"mistral-large-latest\")\n",
    ")\n",
    "\n",
    "gemini_agent = autogen.AssistantAgent(\n",
    "    name=\"Gemini\", system_message=negative_system_message, llm_config=get_llm_config(\"gemini-1.5-pro-latest\")\n",
    ")\n",
    "\n",
    "claude_agent = autogen.AssistantAgent(\n",
    "    name=\"Claude\", system_message=affirmative_system_message, llm_config=get_llm_config(\"claude-3-opus-20240229\")\n",
    ")\n",
    "\n",
    "user_proxy = autogen.UserProxyAgent(\n",
    "    name=\"User\",\n",
    "    code_execution_config=False,\n",
    ")\n",
    "\n",
    "# initialize the groupchat with round robin speaker selection method\n",
    "groupchat = autogen.GroupChat(\n",
    "    agents=[claude_agent, gemini_agent, mistral_agent, llama_agent, gpt35_agent, user_proxy],\n",
    "    messages=[],\n",
    "    max_round=8,\n",
    "    speaker_selection_method=\"round_robin\",\n",
    ")\n",
    "manager = autogen.GroupChatManager(groupchat=groupchat)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "chat_history = user_proxy.initiate_chat(recipient=manager, message=\"Debate Topic: Should vaccination be mandatory?\")"
   ]
  }
 ],
 "metadata": {
  "front_matter": {
   "description": "Uniform interface to call different LLM.",
   "tags": [
    "integration",
    "custom model"
   ]
  },
  "kernelspec": {
   "display_name": "autodev",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
